#include <sys/time.h>
#include "im2col.h"
#include "utils.h"


int main()
{
    constexpr unsigned channels = 32;
    constexpr unsigned input_height = 480; // Example input row size
    constexpr unsigned input_width = 640; // Example input column size
    constexpr unsigned batch_size = 1; // Example batch size
    constexpr unsigned kernel_size = 3; // Example kernel size
    constexpr unsigned stride = 1; // Example stride
    constexpr unsigned padding = 1; // Example padding

    unsigned ifm_size = input_height * input_width * channels;
    unsigned out_height = (input_height + 2 * padding - kernel_size) / stride + 1;
    unsigned out_width  = (input_width  + 2 * padding - kernel_size) / stride + 1;
    unsigned ofm_size = out_height * out_width * kernel_size * kernel_size * channels;
    std::array<unsigned, 2> ifm_shape = {batch_size * input_height * input_width, channels};
    std::array<unsigned, 2> ofm_shape = {batch_size * out_height * out_width, kernel_size * kernel_size * channels};

    data_stream<BIT_ACTV> s_input("s_input");
    data_stream<BIT_ACTV> s_input_golden("s_input_golden");
    data_stream<BIT_ACTV> s_output("s_output");
    data_stream<BIT_ACTV> s_output_golden("s_output_golden");

    gen_ifm(s_input, ifm_shape);
    gen_ifm(s_input_golden, ifm_shape);

    timeval start,end;
    gettimeofday(&start, NULL);
    im2col<batch_size, input_height, input_width, channels, kernel_size, stride, padding, BIT_ACTV, 1, 0>(s_input, s_output);
    im2col_golden<batch_size, input_height, input_width, channels, kernel_size, stride, padding, BIT_ACTV, 1, 0>(s_input_golden, s_output_golden);
    gettimeofday(&end, NULL);

    auto error_cnt = check_afm<BIT_ACTV, 2>(s_output_golden, s_output, ofm_shape);
    if(error_cnt > 0) {
        std::cout << "Test Failed! " << error_cnt << " errors" << std::endl;
        return 1;
    } else {
        std::cout << "Test Passed! " << std::endl;
        return 0;
    }
}
